package main

import (
	"fmt"
	"log"
	"net/http"
	"tuiwen-go/internal/api"
	"tuiwen-go/internal/config"
	"tuiwen-go/internal/db"
	"tuiwen-go/internal/websocket"

	"github.com/gorilla/mux"
	"github.com/rs/cors"
)

func main() {
	// Load configuration
	cfg, err := config.LoadConfig("config.json") // Assuming config.json is in the root
	if err != nil {
		log.Fatalf("Error loading configuration: %v", err)
	}

	// Initialize database connection
	err = db.InitDB(cfg.DB.User, cfg.DB.Password, cfg.DB.Host, cfg.DB.Port, cfg.DB.Database)
	if err != nil {
		log.Fatalf("Error initializing database: %v", err)
	}
	defer db.CloseDB()

	// Initialize settings cache
	err = config.InitSettings()
	if err != nil {
		log.Fatalf("Error initializing settings: %v", err)
	}
	// Start API HTTP server
	apiPort, ok := config.GetSetting("api_port")
	if !ok {
		log.Printf("获取 apiPort 设置失败: gpt_url not found in cache")
		apiPort = "" // Fallback to empty string or default URL
	}
	// Start WebSocket server
	wsPort, ok := config.GetSetting("websocket_port")
	if !ok {
		log.Printf("获取 websocket_port 设置失败: gpt_url not found in cache")
		wsPort = "" // Fallback to empty string or default URL
	}
	// Setup API router
	rAPI := mux.NewRouter()

	// Register API handlers
	rAPI.HandleFunc("/projects/query", api.QueryProjects).Methods("GET")
	rAPI.HandleFunc("/project/query", api.QueryProject).Methods("GET")
	rAPI.HandleFunc("/project/queryRoles", api.QueryProjectRoles).Methods("GET")

	rAPI.HandleFunc("/project/delete", api.DeleteProject).Methods("POST")
	rAPI.HandleFunc("/detail/delete", api.DeleteDetail).Methods("POST")
	rAPI.HandleFunc("/settings/query", api.GetSettings).Methods("GET")
	rAPI.HandleFunc("/settings/update", api.UpdateSetting).Methods("POST")
	rAPI.HandleFunc("/role/new", api.NewRole).Methods("POST")
	rAPI.HandleFunc("/role/delete", api.DeleteRole).Methods("DELETE")
	rAPI.HandleFunc("/role/query", api.QueryRole).Methods("GET")
	rAPI.HandleFunc("/role/queryAll", api.QueryRoles).Methods("GET")
	rAPI.HandleFunc("/speaker/queryAll", api.QuerySpeakers).Methods("GET")

	// Serve static files from the 'public' directory
	// This assumes the 'public' directory is at the same level as the executable.
	// The path prefix is '/public/'
	staticFileServer := http.StripPrefix("/public/", http.FileServer(http.Dir("public")))
	rAPI.PathPrefix("/public/").Handler(staticFileServer)

	// Serve index.html for the root path
	rAPI.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		cookie := &http.Cookie{
			Name:  "ws_port",
			Value: wsPort,
			Path:  "/",
		}
		http.SetCookie(w, cookie)
		http.ServeFile(w, r, "public/html/index.html")
	}).Methods("GET")
	rAPI.HandleFunc("/settings.html", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, "public/html/settings.html")
	}).Methods("GET")

	// Setup CORS middleware for API
	cAPI := cors.New(cors.Options{
		AllowedOrigins:   cfg.AllowedOrigins, // Allow your frontend origin
		AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
		AllowedHeaders:   []string{"*"},
		AllowCredentials: true,
	})
	handlerAPI := cAPI.Handler(rAPI)

	apiAddr := fmt.Sprintf(":%s", apiPort)
	log.Printf("Starting API server on %s", apiAddr)
	go func() {
		if err := http.ListenAndServe(apiAddr, handlerAPI); err != nil {
			log.Fatalf("Error starting API server: %v", err)
		}
	}()

	// Setup WebSocket router
	rWS := mux.NewRouter()
	rWS.HandleFunc("/", websocket.HandleConnections)

	// Apply CORS middleware to WebSocket router
	handlerWS := cAPI.Handler(rWS)

	wsAddr := fmt.Sprintf(":%s", wsPort)
	log.Printf("Starting WebSocket server on %s", wsAddr)
	go func() {
		if err := http.ListenAndServe(wsAddr, handlerWS); err != nil {
			log.Fatalf("Error starting WebSocket server: %v", err)
		}
	}()

	// WebSocket server is handled by the same http.Server
	// The HandleConnections function takes care of the WebSocket protocol upgrade

	// Keep the main goroutine alive
	select {}
}
